﻿using System;
using System.Collections.Generic;
using System.Text;

namespace T.FAS.Runtime.DataAccess.SPI
{
    /// <summary>
    /// 节点对象的关联关系类
    /// </summary>
    /// <remarks>
    /// 1. 关联的配置
    ///    节点对象的关联关系实际是配置在节点对象的元素上。
    ///    设计上数据对象支持复合主键，因此节点对象上存在关联的元素是多个，
    ///    即：一个关联对应一个或者多个节点元素
    /// 2. 由关联带出的外键约束
    ///    在设置元素的关联时，在保存关联的同时，保存对象间的外键关联关系，即：
    ///    哪个表的哪个字段关联哪个表的哪个字段。在保存或者修改关联的主对象时，通过外键关联
    ///    检查存在关联关系的元素的值在关联表中是否存在；在删除或者修改被关联的对象时，通过
    ///    外键关联检查要操作的数据是否被其他表关联引用了。
    /// </remarks>
    [Serializable]
    public class Association : ICloneable
    {
        #region 常量

        /// <summary>
        /// Association
        /// </summary>
        public const string ASSOCIATION = "Association";

        #endregion

        #region 字段

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        public Association()
        {
            RefElementIDs = new List<string>();
            AssociateItems = new AssociateItemCollection();
            RefElements = new List<CommonModelNodeElement>();
            BelongedElements = new List<CommonModelNodeElement>();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id">标识</param>
        /// <param name="currentCommonObject">当前的通用中间对象</param>
        /// <param name="belongNode">隶属的节点对象元素</param>
        /// <param name="mode">关联模式</param>
        /// <param name="AssociationCondition">关联条件</param>
        public Association(string id, AssociateMode mode, string associationCondition = "")
            : this()
        {
            ID = id;
            AssociateMode = mode;
            AssociationCondition = associationCondition;
        }

        #endregion

        #region 属性

        /// <summary>
        /// 标识
        /// </summary>        
        public string ID { get; set; }

        /// <summary>
        /// 关联的名称
        /// </summary>
        /// <remarks>
        /// 主要用于显示和按关联取数
        /// </remarks>
        public string Name { get; set; }

        /// <summary>
        /// 当前关联隶属的节点元素集合
        /// </summary>
        /// <remarks>描述当前关联隶属于哪些节点元素</remarks>
        public List<CommonModelNodeElement> BelongedElements { get; set; }
       
        /// <summary>
        /// 关联的通用中间对象
        /// </summary>
        public CommonModel AssociatedCommonObject { get; set; }

        /// <summary>
        /// 关联的通用中间对象ID
        /// </summary>
        public string AssociatedCommonObjectID
        {
            get
            {
                return AssociatedCommonObject.ID;
            }
        }

        /// <summary>
        /// 关联的节点对象
        /// </summary>
        public CommonModelNode AssociatedNode { get; set; }

        /// <summary>
        /// 关联的节点对象ID
        /// </summary>
        public string AssociatedNodeID
        {
            get
            {
                return AssociatedNode.ID;
            }
        }

        /// <summary>
        /// 关联类型
        /// </summary>        
        public AssociateMode AssociateMode { get; set; }

        /// <summary>
        /// 关联关系中的关联项集合
        /// </summary>  
        /// <remarks>关联中用到了哪些关联项</remarks>
        public AssociateItemCollection AssociateItems { get; set; }

        /// <summary>
        /// 通过关联引用过来的其他通用中间结构上的节点元素
        /// </summary>
        /// <remarks>
        /// 通过其他CO上的Node引用过来的元素
        /// </remarks>
        public List<CommonModelNodeElement> RefElements { get; set; } = new List<CommonModelNodeElement>();


        /// <summary>
        /// 通过关联引用过来的其他通用中间结构上的节点元素ID
        /// </summary>
        public List<string> RefElementIDs { get; set; }

        /// <summary>
        /// 关联条件
        /// </summary>        
        public string AssociationCondition { get; set; }

        //外键约束
        //删除规则

        #endregion

        #region 方法

        /// <summary>
        /// 克隆
        /// </summary>
        /// <returns>节点对象的关联关系的副本</returns>
        public object Clone()
        {
            Association newAssociation = MemberwiseClone() as Association;
            //if (BelongedElements != null)
            //    newAssociation.BelongedElements = BelongedElements.Clone() as GSPCoNodeElementCollection;
            //if (AssociatedNode != null)
            //    newAssociation.AssociatedNode = AssociatedNode.Clone() as GSPCONode;
            //if (AssociateItems != null)
            //    newAssociation.AssociateItems = AssociateItems.Clone() as AssociateItemCollection;
            //if (RefElements != null)
            //    newAssociation.RefElements = RefElements.Clone() as GSPCONodeElementCollection;

            return newAssociation;
        }

        #endregion

    }
}
